﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace BilingualSentIndexing
{
    class SentPairReader
    {
        // Fields
        private byte[] abData;
        private BinaryReader br;
        private int iMaxSentPairSize = 0x2000;
        private long lSizeInMemory;
        private object privateObject = new object();
        private StreamReader sr;

        // Methods
        public void Open(string fileName, double fPercentInMemory)
        {
            if (fPercentInMemory < 0.0)
            {
                fPercentInMemory = 0.0;
            }
            if (fPercentInMemory > 1.0)
            {
                fPercentInMemory = 1.0;
            }
            FileInfo info = new FileInfo(fileName);
            lSizeInMemory = (long)(info.Length * fPercentInMemory);
        //    this.lSizeInMemory -= this.iMaxSentPairSize;
            if (lSizeInMemory < 0)
            {
                lSizeInMemory = 0;
            }
            StreamReader reader = new StreamReader(fileName);
            BinaryReader reader2 = new BinaryReader(Stream.Synchronized(reader.BaseStream));
            this.abData = reader2.ReadBytes((int)this.lSizeInMemory);
            reader2.Close();
            reader.Close();
            this.sr = new StreamReader(fileName);
            this.br = new BinaryReader(Stream.Synchronized(this.sr.BaseStream));
        }

        public void Read(out string englishLine, out string chineseLine, out string strUrl, int offset)
        {
            if (offset + iMaxSentPairSize >= ((int)this.lSizeInMemory))
            {
                this.ReadFromDisk(out englishLine, out chineseLine, out strUrl, offset);
            }
            else
            {
                this.ReadFromMemory(out englishLine, out chineseLine, out strUrl, offset);
            }
        }

        private void ReadFromDisk(out string englishLine, out string chineseLine, out string strUrl, int offset)
        {
            lock (this.privateObject)
            {
                this.br.BaseStream.Seek((long)offset, SeekOrigin.Begin);
                englishLine = br.ReadString();
                chineseLine = br.ReadString();
                strUrl = br.ReadString();
            }
        }

        private void ReadFromMemory(out string englishLine, out string chineseLine, out string strUrl, int offset)
        {
            byte num;
            int count = 0;
            int num3 = 0;
            do
            {
                num = this.abData[offset];
                offset++;
                count |= (num & 0x7f) << num3;
                num3 += 7;
            }while ((num & 0x80) != 0);
            englishLine = Encoding.UTF8.GetString(this.abData, offset, count);
            
            offset += count;
            count = 0;
            num3 = 0;
            do
            {
                num = this.abData[offset];
                offset++;
                count |= (num & 0x7f) << num3;
                num3 += 7;
            }while ((num & 0x80) != 0);
            chineseLine = Encoding.UTF8.GetString(this.abData, offset, count);

            offset += count;
            count = 0;
            num3 = 0;
            do
            {
                num = this.abData[offset];
                offset++;
                count |= (num & 0x7f) << num3;
                num3 += 7;
            } while ((num & 0x80) != 0);
            strUrl = Encoding.UTF8.GetString(this.abData, offset, count);
        }
    }

 

}
